clear; clc;

M = 1500;
N = M;
K = 5;

U = randn(M, K);
V = randn(N, K);
O = U*V';
G = randn(M, N);
D = O + 0.1*G;
ratio = 2*M*K*log(M)/(M*N);
traD = D.*(rand(M, N) < ratio);
traD = sparse(traD);
tstD = (rand(M, N) < ratio);
tstD = O.*tstD;
tstD = sparse(tstD);

para.maxIter = 5000;
para.tau = 1.01;
para.maxTime = 10000;
para.speedup = 1;
para.decay = 0.95;

[trow, tcol, tval] = find(tstD);
para.test.row = trow;
para.test.col = tcol;
para.test.data = tval;
para.test.m = size(tstD, 1);
para.test.n = size(tstD, 2);

clear trow tcol tval tstD;

%% nuclear norm
lambda = 1.3;

% % APG
para.tol = 1e-3;
method = 1;
t = tic;
[U, S, V, out{method, 1}] = APGMatComp(full(traD), lambda, para );
Time(method, 1) = toc(t);
X = U*S*V';

NMSE(method, 1) = norm((X - O), 'fro')/norm(X, 'fro');

% Soft-Impute
para.tol = 1e-1;

method = 2;
t = tic;
para.speedup = 1;
para.decay = 0.97;
para.exact = 1;
[ U, S, V, out{method, 1} ] = SoftImpute( traD, lambda, para);
Time(method, 1) = toc(t);
X = U*S*V';
para.decay = 0.9;

NMSE(method, 1) = norm((X - O), 'fro')/norm(O, 'fro');

% Active
para.tol = 1e-2;
method = 3;
t = tic;
[ U, S, V, out{method, 1} ] = mc_alt( traD, lambda, para );
Time(method, 1) = toc(t);
X = U*S*V';

NMSE(method, 1) = norm((X - O), 'fro')/norm(X, 'fro');

% FastNOCOL
method = 4;
t = tic;
para.speedup = 1;
para.regType = 1;
para.decay = 0.96;
para.maxR  = 100;
[U, S, V, out{method, 1}] = FastMatComp( traD, lambda, 1e+8, para );
Time(method, 1) = toc(t);
X = U*S*V';

NMSE(method, 1) = norm((X - O), 'fro')/norm(O, 'fro');

clear X U S V;

%% Fixed Rank
method = 1;

estRank = 6;
t = tic;
[U, S, V, out{method, 2} ] = SoftImputeALS( traD, 0, estRank, para );
Time(method, 2) = toc(t);
X = U*S*V';

NMSE(method, 2) = norm((X - O), 'fro')/norm(O, 'fro');

method = 2;
estRank = 180;
t = tic;
[U, S, V, out{method, 2} ] = EOR1MP( traD, estRank, para );
Time(method, 2) = toc(t);
X = U*S*V';

NMSE(method, 2) = norm((X - O), 'fro')/norm(O, 'fro');

%%
for i = 3:5
    para.regType = i - 2;
    para.maxR = 6;

    switch(para.regType)
        case 1
            lambda = 50.416080446332050;
            theta  = lambda*2;
        case 2
            lambda = 65.339240258446320;
            theta = sqrt(lambda);
        case 3
            lambda = 50.416080446332050;
            theta = 5;
    end
    
    % NOCOL fast
    method = 1;
    t = tic;
    para.speedup = 1;
    [U, S, V, out{method, i} ] = FastMatComp( traD, lambda, theta, para );
    Time(method, i) = toc(t);
    X = U*S*V';
    NMSE(method, i) = norm((X - O), 'fro')/norm(O, 'fro');
    clear X U S V;
    
    method = 2;
    t = tic;
    para.speedup = 0;
    [U, S, V, out{method, i}] = FastMatComp( traD, lambda, theta, para );
    Time(method, i) = toc(t);
    X = U*S*V';
    NMSE(method, i) = norm((X - O), 'fro')/norm(O, 'fro');
    clear X U S V;

    % GIST fast
    method = 3;
    t = tic;
    para.svdType = 0;
    para.acc = 0;
    [U, S, V, out{method, i}] = GISTMatComp(full(traD), lambda, theta, para);
    Time(method, i) = toc(t);
    X = U*S*V';
    NMSE(method, i) = norm((X - O), 'fro')/norm(O, 'fro');
    clear X U S V;
    
    method = 4;
    t = tic;
    para.svdType = 1;
    [U, S, V, out{method, i}] = GISTMatComp(full(traD), lambda, theta, para);
    Time(method, i) = toc(t);
    X = U*S*V';
    NMSE(method, i) = norm((X - O), 'fro')/norm(O, 'fro');
    clear X U S V;
    
    % IRNN
    method = 5;
    t = tic;
    [U, S, V, out{method, i}] = IRNNMatComp(full(traD), lambda, theta, para);
    Time(method, i) = toc(t);
    X = U*S*V';
    NMSE(method, i) = norm((X - O), 'fro')/norm(O, 'fro');
    clear X U S V;
end

clear D O U V t G traD tstD valD method para lambda i estRank K theta;
 
save(strcat(num2str(M), '-matcomp-3'));
